# Copyright (c) 2024 - 2025 Kevin G. Schlosser

import time
import lvgl as lv
from micropython import const  # NOQA


_SETEXTC = const(0xB9)
_SETPOWER = const(0xB1)
_SETDISP = const(0xB2)
_SETCYC = const(0xB4)
_SETVCOM = const(0xB6)
_SETGIP = const(0xD5)
_SETGAMMA = const(0xE0)
_SETDGCLUT = const(0xC1)
_SETCOLOR = const(0x2D)

_COLMOD = const(0x3A)
_MADCTL = const(0x36)
_SLPOUT = const(0x11)
_DISPON = const(0x29)


def init(self):
    param_buf = bytearray(192)
    param_mv = memoryview(param_buf)

    self.reset()

    # SET password
    param_buf[:3] = bytearray([0xFF, 0x83, 0x69])
    self.set_params(_SETEXTC, param_mv[:3])

    # # SET Freq for fps
    # param_buf[:2] = bytearray([0x01, 0x08])
    # self.set_params(0xB0, param_mv[:2])

    # Set Power
    param_buf[:19] = bytearray([
        0x01, 0x00, 0x34, 0x06, 0x00, 0x0f, 0x0f, 0x2a, 0x32, 0x3f,
        0x3f, 0x07, 0x23, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6])

    self.set_params(_SETPOWER, param_mv[:19])

    # SET Display  480x800
    param_buf[:15] = bytearray([
        0x00, 0x20, 0x03, 0x03, 0x70, 0x00, 0xff, 0x00,
        0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01])

    self.set_params(_SETDISP, param_mv[:15])

    # SET Display  column inversion
    param_buf[:5] = bytearray([0x00, 0x0C, 0xA0, 0x0E, 0x06])
    self.set_params(_SETCYC, param_mv[:5])

    # SET VCOM
    param_buf[:2] = bytearray([0x2C, 0x2C])
    self.set_params(_SETVCOM, param_mv[:2])

    # SET GIP
    param_buf[:26] = bytearray([
        0x00, 0x05, 0x03, 0x00, 0x01, 0x09, 0x10, 0x80, 0x37,
        0x37, 0x20, 0x31, 0x46, 0x8a, 0x57, 0x9b, 0x20, 0x31,
        0x46, 0x8a, 0x57, 0x9b, 0x07, 0x0f, 0x02, 0x00])

    self.set_params(_SETGIP, param_mv[:26])

    # Set Gamma
    param_buf[:34] = bytearray([
        0x00, 0x08, 0x0d, 0x2d, 0x34, 0x3f, 0x19, 0x38, 0x09,
        0x0e, 0x0e, 0x12, 0x14, 0x12, 0x14, 0x13, 0x19, 0x00,
        0x08, 0x0d, 0x2d, 0x34, 0x3f, 0x19, 0x38, 0x09, 0x0e,
        0x0e, 0x12, 0x14, 0x12, 0x14, 0x13, 0x19])

    self.set_params(_SETGAMMA, param_mv[:34])

    # Set DGC
    param_buf[:127] = bytearray([
        0x01, 0x02, 0x08, 0x12, 0x1a, 0x22, 0x2a, 0x31, 0x36,
        0x3f, 0x48, 0x51, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80,
        0x88, 0x90, 0x98, 0xa0, 0xa7, 0xaf, 0xb6, 0xbe, 0xc7,
        0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf5, 0xfb, 0xfc, 0xfe,
        0x8c, 0xa4, 0x19, 0xec, 0x1b, 0x4c, 0x40, 0x02, 0x08,
        0x12, 0x1a, 0x22, 0x2a, 0x31, 0x36, 0x3f, 0x48, 0x51,
        0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90, 0x98,
        0xa0, 0xa7, 0xaf, 0xb6, 0xbe, 0xc7, 0xce, 0xd6, 0xde,
        0xe6, 0xef, 0xf5, 0xfb, 0xfc, 0xfe, 0x8c, 0xa4, 0x19,
        0xec, 0x1b, 0x4c, 0x40, 0x02, 0x08, 0x12, 0x1a, 0x22,
        0x2a, 0x31, 0x36, 0x3f, 0x48, 0x51, 0x58, 0x60, 0x68,
        0x70, 0x78, 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa7, 0xaf,
        0xb6, 0xbe, 0xc7, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf5,
        0xfb, 0xfc, 0xfe, 0x8c, 0xa4, 0x19, 0xec, 0x1b, 0x4c, 0x40])

    self.set_params(_SETDGCLUT, param_mv[:127])

    #  Colour Set
    for i in range(64):
        param_buf[i] = i * 8

    for i in range(64, 128, 1):
        param_buf[i] = i * 4

    for i in range(128, 192, 1):
        param_buf[i] = i * 8

    self.set_params(_SETCOLOR, param_mv[:192])

    # LCD goes into sleep mode and display will be turned off after 
    # power on reset, exit sleep mode first
        
    self.set_params(_SLPOUT)
    time.sleep_ms(100)  # NOQA
    
    param_buf[0] = self._madctl(
        self._color_byte_order, self._ORIENTATION_TABLE)
    self.set_params(_MADCTL, param_mv[:1])
    
    color_size = lv.color_format_get_size(self._color_space)
    if color_size == 2:  # NOQA
        param_buf[0] = 0x55
    elif color_size == 3:
        param_buf[0] = 0x66
    else:
        raise RuntimeError('unsupported color format')

    self.set_params(_COLMOD, param_mv[:1])
    self.set_params(_DISPON)
